package com.ibiaoke.order.service;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.ibiaoke.common.base.Page;
import com.ibiaoke.common.configs.GlobalConfigs;
import com.ibiaoke.common.configs.GlobalConfigsKey;
import com.ibiaoke.common.configs.WeChatConfigs;
import com.ibiaoke.common.consts.CommonConsts;
import com.ibiaoke.common.exception.ServiceException;
import com.ibiaoke.common.spring.ExceptionAspect;
import com.ibiaoke.common.utils.*;
import com.ibiaoke.customer.dao.CustomerDao;
import com.ibiaoke.customer.entity.Customer;
import com.ibiaoke.customer.entity.ThirdPartLogin;
import com.ibiaoke.customer.entity.XcxOpenGroup;
import com.ibiaoke.customer.service.DepositRecorderService;
import com.ibiaoke.customer.service.DepositService;
import com.ibiaoke.goods.dao.XcxGoodsDao;
import com.ibiaoke.goods.dao.XcxShopPriceDao;
import com.ibiaoke.goods.entity.Goods;
import com.ibiaoke.goods.entity.XcxGoods;
import com.ibiaoke.goods.entity.XcxShopPrice;
import com.ibiaoke.goods.entity.XcxShopPriceExample;
import com.ibiaoke.order.consts.OrderStatusConst;
import com.ibiaoke.order.consts.XcxOrderStatusConst;
import com.ibiaoke.order.dao.ShoppingCartDao;
import com.ibiaoke.order.dao.XcxAddressDao;
import com.ibiaoke.customer.dao.XcxOpenGroupDao;
import com.ibiaoke.order.dao.XcxOrderDao;
import com.ibiaoke.order.entity.*;
import com.ibiaoke.order.entity.so.SubmitOrderSO;
import com.ibiaoke.order.entity.so.XcxOrderSO;
import com.ibiaoke.order.entity.vo.DateAnalysisVO;
import com.ibiaoke.order.entity.vo.XcxOrderVO;
import com.ibiaoke.system.dao.ShopDao;
import com.ibiaoke.system.entity.Shop;
import com.ibiaoke.system.entity.dto.DeliverInfoDTO;
import com.ibiaoke.system.service.ShopService;
import com.ibiaoke.system.service.XcxShopService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.security.KeyStore;
import java.util.*;

import static com.ibiaoke.common.utils.StringUtils.nullToEmpty;
import static java.util.stream.Collectors.toList;

/**
 * @author Healer
 * @date 2018/3/7/16:55;
 */
@Service("xcxOrderService")
public class XcxOrderServiceImpl implements XcxOrderService {

    private static Logger logger = LoggerFactory.getLogger(ExceptionAspect.class);

    @Autowired
    private XcxOrderDao xcxOrderDao;

    @Autowired
    private XcxOpenGroupDao xcxOpenGroupDao;

    @Autowired
    private XcxGoodsDao xcxGoodsDao;

    @Autowired
    private XcxAddressDao xcxAddressDao;

    @Autowired
    private ShopDao shopDao;

    @Autowired
    private ShopService shopService;

    @Autowired
    private XcxOpenGroupService xcxOpenGroupService;

    @Autowired
    private XcxShopService xcxShopService;

    @Autowired
    private XcxShopPriceDao xcxShopPriceDao;

    @Autowired
    private ShoppingCartService shoppingCartService;

    @Autowired
    private ShoppingCartGoodsService shoppingCartGoodsService;

    @Autowired
    private ShoppingCartDao shoppingCartDao;

    @Autowired
    private DepositService depositService;

    @Autowired
    private DepositRecorderService depositRecorderService;

    @Autowired
    private CustomerDao customerDao;

    @Override
    public XcxOrder submitXcxGoodsOrder(Customer customer, Integer xcxGoodsId, Integer addressId, Integer deliveryType,
                                        ThirdPartLogin thirdPartLogin, Integer shopId, String remark, Integer expressPrice,
                                        Integer paymentType) {
        XcxGoods xcxGood = xcxGoodsDao.getXcxGoodsByGoodsId(xcxGoodsId, shopId);
        if (xcxGood != null) {
            if (xcxGood.getStatus() == 0) {
                throw new ServiceException("此商品已下架");
            }
            if (xcxGood.getStockNum() <= 0) {
                throw new ServiceException("此商品已售罄");
            }
        }
        AssertUtils.notNull(customer, "请先登录");
        //存开团信息
        XcxOpenGroup xcxOpenGroup = new XcxOpenGroup();
        xcxOpenGroup.setOpenCode(generateOrderNo());
        xcxOpenGroup.setIsOpen(1);
        xcxOpenGroup.setPtType(xcxGood.getPtType());
        xcxOpenGroup.setUserId(customer.getCustomerId());
        xcxOpenGroup.setPtCount(xcxGood.getPtType());
        xcxOpenGroup.setUserName(thirdPartLogin.getNickName());
        xcxOpenGroup.setUserImg(thirdPartLogin.getHeadImageUrl());
        xcxOpenGroup.setPtGoodsId(xcxGood.getGoodsId());
        xcxOpenGroup.setStatus(CommonConsts.YES);
        xcxOpenGroup.setIsPay(CommonConsts.NO);
        xcxOpenGroup.setPayType(paymentType);
        xcxOpenGroup.setOpenTime(new Date());
        xcxOpenGroup.setUpdateTime(new Date());
        xcxOpenGroup.setRemark1(shopId.toString());
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.DATE, 1);
        xcxOpenGroup.setEndTime(c.getTime());
        XcxOpenGroup xcxOpenGroup1 = xcxOpenGroupDao.saveXcxOpenGroup(xcxOpenGroup);
        //存订单信息
        XcxOrder xcxOrder = new XcxOrder();
        xcxOrder.setUserId(customer.getCustomerId());
        xcxOrder.setOrderCode(generateOrderNo());
        xcxOrder.setGroupId(xcxOpenGroup1.getGroupId());
        xcxOrder.setGoodId(xcxGoodsId);
        xcxOrder.setIsopen(new Byte("1"));
        xcxOrder.setOpenCode(xcxOpenGroup1.getOpenCode());
        xcxOrder.setOrderType(new Byte("1"));
        xcxOrder.setOrderStatus(0);
        if (deliveryType == 0) {
            XcxAddress address = xcxAddressDao.selectByPrimaryKey(addressId);
            xcxOrder.setShopId(shopId);
            xcxOrder.setDeliveryType(0);
            xcxOrder.setDeliveryLocationId(addressId);
            xcxOrder.setDeliveryAddress(address.toDetailAddress());
            xcxOrder.setContactMobile(address.getContactPhone());
            xcxOrder.setContactPersion(address.getContactName());
        } else if (deliveryType == 1) {
            xcxOrder.setDeliveryType(1);
            xcxOrder.setShopId(shopId);
            Shop shop = shopDao.getShopByShopId(shopId);
            xcxOrder.setDeliveryAddress(shop.getShopName());
        }
        xcxOrder.setRemarke(remark);
        xcxOrder.setExpressPrice(new BigDecimal(expressPrice));
        xcxOrder.setOrderPrice(xcxOrder.getExpressPrice().add(xcxGood.getPtPrice()));
        xcxOrder.setRemark2(xcxGood.getPtPrice().toString());
        xcxOrder.setCouponPrice(new BigDecimal(0));
        xcxOrder.setPayType(paymentType);
        xcxOrder.setDelStatus(new Byte("0"));
        xcxOrder.setCreateTime(new Date());
        xcxOrder.setUpdateTime(new Date());
        xcxOrder.setSource("XcxPt");
        xcxOrder.setOldGoodsName(xcxGood.getName() + " " + xcxGood.getPtPrice() + "元 (" + xcxGood.getPtType() + "人团)");
        xcxOrder.setEndTime(c.getTime());
        xcxOrderDao.saveXcxOrder(xcxOrder);
        XcxOrder xcxOrder1 = xcxOrderDao.getOrderByOrderCode(xcxOrder.getOrderCode());
        return xcxOrder1;
    }

    @Override
    public XcxOrder joinXcxOpenGroup(XcxOpenGroup xcxOpenGroup, Customer customer, ThirdPartLogin thirdPartLogin, Integer deliveryType,
                                     Integer addressId, Integer shopId, String remark, Integer expressPrice, Integer paymentType) {

        AssertUtils.notNull(customer.getCustomerId(), "用户Id不能为空");
        AssertUtils.notBlank(xcxOpenGroup.getOpenCode(), "开团码不能为空");

        List<XcxOpenGroup> xcxOpenGroupList = xcxOpenGroupService.checkXcxOpenGroup
                (xcxOpenGroup.getOpenCode(), xcxOpenGroup.getPtGoodsId(), customer.getCustomerId());
        if (xcxOpenGroupList != null && xcxOpenGroupList.size() > 0) {
            for (XcxOpenGroup thisXcxOpenGroup : xcxOpenGroupList) {
                if (thisXcxOpenGroup.getIsPay() == 1) {
                    throw new ServiceException("别闹！你已经在里面了!");
                }
            }
        }
        AssertUtils.requireTrue(xcxOpenGroup.getPtCount() > 0, "您的手速慢了！");

        XcxGoods xcxGood = xcxGoodsDao.getXcxGoodsByGoodsId(xcxOpenGroup.getPtGoodsId(), shopId);
        AssertUtils.notNull(xcxGood, "拼团商品不存在");
        if (xcxGood.getStockNum() <= 0) {
            throw new ServiceException("此商品已售罄");
        }

        XcxOpenGroup xcxOpenGroup2 = new XcxOpenGroup();
        xcxOpenGroup2.setOpenCode(xcxOpenGroup.getOpenCode());
        xcxOpenGroup2.setIsOpen(0);
        xcxOpenGroup2.setPtType(xcxOpenGroup.getPtType());
        xcxOpenGroup2.setUserId(customer.getCustomerId());
        xcxOpenGroup2.setPtCount(xcxOpenGroup.getPtCount());
        xcxOpenGroup2.setUserName(thirdPartLogin.getNickName());
        xcxOpenGroup2.setUserImg(thirdPartLogin.getHeadImageUrl());
        xcxOpenGroup2.setPtGoodsId(xcxGood.getGoodsId());
        xcxOpenGroup2.setStatus(CommonConsts.YES);
        xcxOpenGroup2.setIsPay(CommonConsts.NO);
        xcxOpenGroup2.setPayType(paymentType);
        xcxOpenGroup2.setOpenTime(new Date());
        xcxOpenGroup2.setUpdateTime(new Date());
        xcxOpenGroup2.setEndTime(xcxOpenGroup.getEndTime());
        xcxOpenGroup.setRemark1(shopId.toString());
        xcxOpenGroupDao.saveXcxOpenGroup(xcxOpenGroup2);

        //存订单信息
        XcxOrder xcxOrder = new XcxOrder();
        xcxOrder.setUserId(customer.getCustomerId());
        xcxOrder.setOrderCode(generateOrderNo());
        xcxOrder.setGroupId(xcxOpenGroup2.getGroupId());
        xcxOrder.setGoodId(xcxOpenGroup.getPtGoodsId());
        xcxOrder.setIsopen(new Byte("0"));
        xcxOrder.setOpenCode(xcxOpenGroup2.getOpenCode());
        xcxOrder.setOrderType(new Byte("2"));
        xcxOrder.setOrderStatus(0);
        if (deliveryType == 0) {
            xcxOrder.setShopId(shopId);
            XcxAddress address = xcxAddressDao.selectByPrimaryKey(addressId);
            xcxOrder.setDeliveryType(0);
            xcxOrder.setDeliveryLocationId(addressId);
            xcxOrder.setDeliveryAddress(address.toDetailAddress());
            xcxOrder.setContactMobile(address.getContactPhone());
            xcxOrder.setContactPersion(address.getContactName());
        } else if (deliveryType == 1) {
            xcxOrder.setDeliveryType(1);
            xcxOrder.setShopId(shopId);
            Shop shop = shopDao.getShopByShopId(shopId);
            xcxOrder.setDeliveryAddress(shop.getShopName());
        }
        xcxOrder.setRemarke(remark);
        xcxOrder.setExpressPrice(new BigDecimal(expressPrice));
        xcxOrder.setOrderPrice(xcxOrder.getExpressPrice().add(xcxGood.getPtPrice()));
        xcxOrder.setRemark2(xcxGood.getPtPrice().toString());
        xcxOrder.setCouponPrice(new BigDecimal(0));
        xcxOrder.setDelStatus(new Byte("0"));
        xcxOrder.setPayType(paymentType);
        xcxOrder.setCreateTime(new Date());
        xcxOrder.setUpdateTime(new Date());
        xcxOrder.setSource("XcxJt");
        xcxOrder.setOldGoodsName(xcxGood.getName() + " " + xcxGood.getPtPrice() + " 元 (" + xcxGood.getPtType() + "人团)");
        xcxOrder.setEndTime(xcxOpenGroup.getEndTime());
        xcxOrderDao.saveXcxOrder(xcxOrder);
        XcxOrder xcxOrder1 = xcxOrderDao.getOrderByOrderCode(xcxOrder.getOrderCode());
        return xcxOrder1;
    }

    public static void main(String[] args) {
        System.out.println(new BigDecimal("0.01").toString());
    }

    @Override
    public XcxOrder XcxGoodsOrder(SubmitOrderSO submitOrderSO) {
        AssertUtils.notNull(submitOrderSO.getGoodsId(), "请选择商品");
        AssertUtils.notNull(submitOrderSO.getUserId(), "请先登录");
        XcxGoods xcxGood = xcxGoodsDao.getXcxGoodsByGoodsId(submitOrderSO.getGoodsId(), submitOrderSO.getShopId());
        if (xcxGood.getStatus() == 0) {
            throw new ServiceException("此商品已下架");
        }
        if (xcxGood.getStockNum() <= 0) {
            throw new ServiceException("此商品已售罄");
        }
        XcxOrder xcxOrder = new XcxOrder();
        xcxOrder.setUserId(submitOrderSO.getUserId());
        xcxOrder.setOrderCode(generateOrderNo());
        xcxOrder.setGoodId(submitOrderSO.getGoodsId());
        xcxOrder.setOrderType(new Byte("0"));
        xcxOrder.setOrderStatus(0);
        xcxOrder.setGoodNum(submitOrderSO.getNum());
        if (submitOrderSO.getDeliveryType().equals("0")) {
            XcxAddress address = xcxAddressDao.selectByPrimaryKey(submitOrderSO.getAddressId());
            xcxOrder.setShopId(submitOrderSO.getShopId());
            xcxOrder.setDeliveryType(0);
            xcxOrder.setDeliveryLocationId(submitOrderSO.getAddressId());
            xcxOrder.setDeliveryAddress(address.toDetailAddress());
            xcxOrder.setContactMobile(address.getContactPhone());
            xcxOrder.setContactPersion(address.getContactName());
        } else if (submitOrderSO.getDeliveryType().equals("1")) {
            xcxOrder.setDeliveryType(1);
            xcxOrder.setShopId(submitOrderSO.getShopId());
            Shop shop = shopDao.getShopByShopId(submitOrderSO.getShopId());
            xcxOrder.setDeliveryAddress(shop.getShopName());
        }
        if (xcxGood.getPtType() != null) {
            xcxOrder.setOldGoodsName(xcxGood.getName() + " " + xcxGood.getPrice() + " 元 (" + xcxGood.getPtType() + "人团)");
        } else {
            xcxOrder.setOldGoodsName(xcxGood.getName() + " " + xcxGood.getPrice() + " 元 (无拼团)");
        }
        xcxOrder.setRemarke(submitOrderSO.getRemarke());
        xcxOrder.setExpressPrice(new BigDecimal(submitOrderSO.getExpressPrice()));//运费
        BigDecimal goodPrice = xcxGood.getPrice().multiply(new BigDecimal(submitOrderSO.getNum())); //商品金额*数量
        BigDecimal ordrePrice = goodPrice.add(new BigDecimal(submitOrderSO.getExpressPrice()));//商品金额+运费
        xcxOrder.setOrderPrice(ordrePrice.setScale(2, BigDecimal.ROUND_HALF_UP));//订单价格
        xcxOrder.setRemark2((goodPrice.setScale(2, BigDecimal.ROUND_HALF_UP).toString()));//商品金额
        xcxOrder.setCouponPrice(new BigDecimal(0));
        xcxOrder.setDelStatus(new Byte("0"));
        xcxOrder.setPayType(submitOrderSO.getPaymentType());
        System.out.println(" 创建订单，现在的时间是 :" + new Date());
        xcxOrder.setCreateTime(new Date());
        xcxOrder.setUpdateTime(new Date());
        xcxOrder.setSource("Xcx");
        xcxOrder.setEndTime(new Date());
        xcxOrderDao.saveXcxOrder(xcxOrder);
        XcxOrder xOrder = xcxOrderDao.getOrderByOrderCode(xcxOrder.getOrderCode());
        return xOrder;
    }
    @Override
    public void updateXcxOrderStatus(XcxOrder xcxOrder) {
        xcxOrderDao.updateXcxOrderStatus(xcxOrder);
    }

    @Override
    public List<XcxOrder> xcxOrderList(XcxOrderVO xcxOrder, Page page) {
        List<XcxOrder> orderList = xcxOrderDao.xcxOrderList(xcxOrder, page);
        XcxShopPriceExample example = new XcxShopPriceExample();
        List<XcxShopPrice> shopPriceList = xcxShopPriceDao.selectByExample(example);


        orderList.forEach(xcxOrder1 -> shopPriceList.forEach(shopPrice -> {
            if (Objects.equals(xcxOrder1.getShopId(), shopPrice.getShopId()) &&
                    Objects.equals(xcxOrder1.getGoodId(), shopPrice.getGoodsId())) {
                xcxOrder1.setXcxShopPrice(shopPrice);
            }
        }));

/*         if(orderList != null && orderList.size()>0){
             for(int i = 0; i<orderList.size();i++){
                 if(orderList.get(i).getGoodId() != null){
                     XcxGoods xGoods = xcxGoodsDao.getXcxGoodsByGoodsId(orderList.get(0).getGoodId(),orderList.get(i).getShopId());
                     orderList.get(i).setXcxGoods(xGoods);
                 }
             }
         }*/
        return orderList;
    }

    @Override
    public int ConfirmOrder(Customer customer, XcxOrder xcxOrder) {
        AssertUtils.notNull(customer.getCustomerId(), "用户Id不能为空");
        AssertUtils.notNull(xcxOrder.getOrderId(), "订单Id不能为空");
        return xcxOrderDao.ConfirmOrder(customer, xcxOrder);
    }


    @Override
    public int delXcxOrder(Customer customer, Integer orderId) {
        AssertUtils.notNull(customer.getCustomerId(), "用户Id不能为空");
        AssertUtils.notNull(orderId, "订单Id不能为空");
        return xcxOrderDao.delXcxOrder(customer.getCustomerId(), orderId);
    }

    public String generateOrderNo() {
        String dateNo = DateUtils.formatOrderNoDate(new Date());
        return dateNo + RandomUtils.generatorOrderNo();
    }
    @Override
    @Transactional
    public void updateOrderStatus(XcxOrder xcxOrder) {
        //更新order的pay_time 和 update_time
        xcxOrderDao.updatePayTimeAndUpdateTime(xcxOrder);
        //更新openOrder的is_pay为1
        xcxOpenGroupDao.updateIspayAndCount(xcxOrder.getGroupId());
        //获取开团人的信息
        XcxOpenGroup xcxOpenGroup = xcxOpenGroupDao.getXcxOpenGroupByOpenCode(xcxOrder.getOpenCode());
        if (xcxOpenGroup.getPtCount() == 1 || xcxOpenGroup.getPtCount() == 0) {
            //更改所有订单状态为3(待收货)
            List<XcxOrder> xcxOrderList = xcxOrderDao.getXcxOrderList(xcxOpenGroup.getOpenCode());
            for (XcxOrder xcxOrder1 : xcxOrderList) {
                if (xcxOrder1.getPayTime() != null) {
                    xcxOrderDao.upPtOrderStatus(xcxOrder1.getOrderId(), 3);
                }
            }
            //可剩余开团数-1
            if (xcxOpenGroup.getPtCount() > 0) {
                xcxOpenGroupDao.updateXcxOpenGroupCount(xcxOpenGroup, xcxOpenGroup.getPtCount() - 1);
            }
            XcxGoods xcxGood = xcxGoodsDao.getXcxGoodsByGoodsId(xcxOrder.getGoodId(), xcxOrder.getShopId());
            //更改售出数量
            xcxGoodsDao.updatePtXcxGoodSaleNum(xcxGood);
            //更改库存
            xcxShopPriceDao.updatePtXcxGoodStockNum(xcxOrder.getGoodId(), xcxOrder.getShopId(), xcxGood.getPtType());
            //发送短信
            sendPtOrderMessage(xcxOrder);
        } else {
            xcxOrderDao.upPtOrderStatus(xcxOrder.getOrderId(), 1);
            if (xcxOpenGroup.getPtCount() > 0) {
                xcxOpenGroupDao.updateXcxOpenGroupCount(xcxOpenGroup, xcxOpenGroup.getPtCount() - 1);
            }
        }
    }

    @Override
    public void sendPtOrderMessage(XcxOrder xcxOrder) {
        Shop nearestShop = null;
        if (xcxOrder.getShopId() != null && xcxOrder.getShopId() != 0) {
            nearestShop = xcxShopService.getShpopById(xcxOrder.getShopId());
        }
        if (nearestShop == null) {
            nearestShop = shopService.getNearestShop(xcxOrder.getLongitude(), xcxOrder.getLatitude());
            xcxOrder.setShopId(nearestShop.getShopId());
            xcxOrderDao.updateOrderShop(xcxOrder.getOrderId(), nearestShop.getShopId());
        }
        String template = "JSM40225-0009";
        StringBuilder content = getPtOrderSmsContent(xcxOrder, nearestShop);
        /*if (content.length() >= 300) {
            content = getPtOrderSmsUrlContent(xcxOrder, nearestShop);
            template = GlobalConfigs.getConfigure(GlobalConfigsKey.SMS_TEMPLATE_ORDER_URL);
        }*/
        SmsUtil.sendOrderMsgWithTemp(nearestShop.getShopMobile(), template, content.toString());
    }

    @Override
    public Integer cancelOrder(Integer userId, Integer orderId) {
        AssertUtils.notNull(userId, "客户Id不能为空");
        AssertUtils.notNull(orderId, "订单Id不能为空");
        XcxOrder order = xcxOrderDao.selectByPrimaryKey(orderId);
        AssertUtils.requireEquals(userId, order.getUserId(), "不要调皮哦");
        AssertUtils.requireTrue(order.getOrderStatus() == OrderStatusConst.UNPAID, "已支付订单不能取消");
        return xcxOrderDao.cancelOrder(userId, orderId);
    }

    @Override
    public String aggregate(Integer serviceNum, Date startTime, Date endTime) {
        List<XcxOrder> xcxOrderList = xcxOrderDao.aggregate(serviceNum, startTime, endTime);
        //订单总价
        BigDecimal totalPrice = xcxOrderList.stream().map(XcxOrder::getOrderPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
        return totalPrice.add(totalPrice).toString();
    }

    public StringBuilder getPtOrderSmsContent(XcxOrder orderInfo, Shop nearestShop) {
        StringBuilder content = new StringBuilder();
        content.append("@1@=" + nearestShop.getShopName() + ",");
        XcxGoods xcxGood = xcxGoodsDao.selectByPrimaryKey(orderInfo.getGoodId());
        content.append("\n[拼团时间:]" + new Date());
        content.append("\n[订单类型]：拼团");
        if (xcxGood != null) {
            content.append("\n[拼团类型]: " + xcxGood.getPtType());
            content.append("\n[商品名称:]" + xcxGood.getName());
            content.append("\n[商品规格:]" + nullToEmpty(xcxGood.getSpec()) + ",");
            content.append("\n[商品金额:]" + xcxGood.getPtPrice());
        }
        content.append("\n[订单来源:]微信小程序");
        return content;
    }

    @Transactional
    @Override
    public void updateOrderStatusByOnly(XcxOrder xcxOrder) {
        xcxOrderDao.updatePayTimeAndUpdateTime(xcxOrder);
        xcxOrderDao.upPtOrderStatus(xcxOrder.getOrderId(), 3);
        if (xcxOrder.getGoodId() != null) {
            //售出数量
            xcxGoodsDao.updateXcxGoodSaleNumByNum(xcxOrder.getGoodId(), xcxOrder.getGoodNum());
            //减去库存
            xcxShopPriceDao.updateXcxShopPriceStockNum(xcxOrder.getGoodId(), xcxOrder.getGoodNum(), xcxOrder.getShopId());
        }
        //发送短信
        sendOrderMessage(xcxOrder);
    }

    @Override
    public XcxOrder getOrderById(Integer orderId) {
        AssertUtils.notNull(orderId, "订单ID不能为空");
        XcxOrder order = xcxOrderDao.getOrderById(orderId);
        if (order != null && order.getGoodId() != null) {
            XcxGoods xGoods = xcxGoodsDao.getXcxGoodsByGoodsId(order.getGoodId(), order.getShopId());
            order.setXcxGoods(xGoods);
        }
        return order;
    }


    public Long getNoPaycount(Integer customerId) {
        AssertUtils.notNull(customerId, "用户ID不能为空");
        XcxOrderExample example = new XcxOrderExample();
        example.createCriteria().andUserIdEqualTo(customerId).andOrderStatusEqualTo(XcxOrderStatusConst.UNPAID);
        return xcxOrderDao.countByExample(example);
    }


    public Long getOrderCount(Integer customerId) {
        AssertUtils.notNull(customerId, "用户ID不能为空");
        XcxOrderExample example = new XcxOrderExample();
        example.createCriteria().andUserIdEqualTo(customerId);
        return xcxOrderDao.countByExample(example);
    }

    @Override
    public Long getOrderCountByStatus(Integer customerId, Integer status) {
        AssertUtils.notNull(customerId, "用户ID不能为空");
        AssertUtils.notNull(status, "状态不能为空");
        return xcxOrderDao.getOrderCountByStatus(customerId, status);
    }

    @Override
    public void sendOrderMessage(XcxOrder xcxOrderInfo) {
        Shop nearestShop = null;
        if (xcxOrderInfo.getShopId() != null && xcxOrderInfo.getShopId() != 0) {
            nearestShop = xcxShopService.getShpopById(xcxOrderInfo.getShopId());
        }
        if (nearestShop == null) {
            nearestShop = shopService.getNearestShop(xcxOrderInfo.getLongitude(), xcxOrderInfo.getLatitude());
            xcxOrderInfo.setShopId(nearestShop.getShopId());
            xcxOrderDao.updateOrderShop(xcxOrderInfo.getOrderId(), nearestShop.getShopId());
        }
        String template = "JSM40225-0004";
        StringBuilder content = getOrderSmsContent(xcxOrderInfo, nearestShop);
        if (content.length() >= 300) {
            content = getOrderSmsUrlContent(xcxOrderInfo, nearestShop);
            template = GlobalConfigs.getConfigure(GlobalConfigsKey.SMS_TEMPLATE_ORDER_URL);
        }
        SmsUtil.sendOrderMsgWithTemp(nearestShop.getShopMobile(), template, content.toString());
    }

    public StringBuilder getOrderSmsContent(XcxOrder orderInfo, Shop nearestShop) {
        StringBuilder content = new StringBuilder();
        XcxGoods xcxGood = null;
        content.append("@1@=" + nearestShop.getShopName() + ",");
        content.append("@2@=" + orderInfo.getOrderCode() + ",");
        xcxGood = xcxGoodsDao.getXcxGoodsByGoodsId(orderInfo.getGoodId(), orderInfo.getShopId());
        if (xcxGood != null) {
            StringBuilder goodsInfoContent = new StringBuilder();
            if (orderInfo.getOrderType() == 0) {
                goodsInfoContent.append(xcxGood.getName() + "(" + xcxGood.getSpec() + xcxGood.getPrice() + " * " + orderInfo.getGoodNum() + ")\n");
            } else {
                goodsInfoContent.append(xcxGood.getName() + "(" + xcxGood.getSpec() + xcxGood.getPrice() + ")\n");
            }
            content.append("@3@=" + goodsInfoContent.toString().replace(",", "") + " ,");
        } else {
            content.append("@3@=" + " ,");
        }
        content.append("@4@=" + nullToEmpty(orderInfo.getContactPersion()) + ",");
        content.append("@5@=" + nullToEmpty(orderInfo.getContactMobile()) + ",");
        content.append("@6@=" + nullToEmpty(orderInfo.getDeliveryAddress()) + " 备注：" + nullToEmpty(orderInfo.getRemarke()));
        String deliveryType = orderInfo.getDeliveryType().intValue() == 1 ? "自提" : "快递";
        content.append("\n[配送类型:]" + deliveryType);
        content.append("\n[实付金额:]" + (orderInfo.getOrderPrice().subtract(orderInfo.getExpressPrice())).setScale(2, BigDecimal.ROUND_HALF_UP) + "元");
        content.append("\n[运费:]" + orderInfo.getExpressPrice() + "元");
        content.append("\n[优惠券抵扣金额:]" + orderInfo.getCouponPrice() + "元");
        content.append("\n[订单来源:]微信小程序");
        return content;
    }

    public StringBuilder getOrderSmsUrlContent(XcxOrder orderInfo, Shop nearestShop) {
        StringBuilder content = new StringBuilder();

        content.append("@1@=" + nearestShop.getShopName() + ",");
        content.append("@2@=" + orderInfo.getOrderCode() + ",");

        String code = DesUtils.encrypt(String.valueOf(orderInfo.getOrderId()));
        content.append("@3@=" + code + "\n" + SmsUtil.SMS_WITH_URL_FLAG + " ,");
        content.append("@4@=" + nullToEmpty(orderInfo.getContactPersion()) + ",");
        content.append("@5@=" + nullToEmpty(orderInfo.getContactMobile()) + ",");
        content.append("@6@=" + nullToEmpty(orderInfo.getDeliveryAddress()) + " 备注：" + nullToEmpty(orderInfo.getRemarke()));
        String deliveryType = orderInfo.getDeliveryType().intValue() == 1 ? "自提" : "快递";
        content.append("\n[配送类型:]" + deliveryType);
        content.append("\n[实付金额:]" + (orderInfo.getOrderPrice().subtract(orderInfo.getExpressPrice())).setScale(2, BigDecimal.ROUND_HALF_UP) + "元");
        content.append("\n[运费:]" + orderInfo.getExpressPrice() + "元");
        content.append("\n[优惠券抵扣金额:]" + orderInfo.getCouponPrice() + "元");
        content.append("\n[订单来源:]微信小程序");
        return content;
    }

    @Override
    public void updateWaitPayXcxOrder() {
        logger.info("updateWaitPayXcxOrder");
        xcxOrderDao.updateWaitPayXcxOrder();
    }

    @Override
    public void xcxConfirmOrder() {
        logger.info("xcxConfirmOrder");
        //获取所有订单状态为3(待收货)的订单
        List<XcxOrder> xcxOrderList = xcxOrderDao.getXcxOrderByStatus(3);
        //查询创建时间>72小时的订单，更改状态为4(已完成)
        xcxOrderDao.xcxConfirmOrder(xcxOrderList);
    }

    @Override
    public void updateOverTimeXcxPtOrder() {
        logger.info("updateOverTimeXcxPtOrder");
        //获取所有订单状态为1的订单
        List<XcxOrder> xcxOrderList = xcxOrderDao.getXcxOrderByStatus(1);
        //查询创建时间>24小时的订单，更改状态为6
        xcxOrderDao.updateOverTimeXcxPtOrder(xcxOrderList);
    }

    @Override
    public void XcxPtPayRefund() {
        logger.info("XcxPtPayRefund");
        //获取所有订单状态为6的订单
        List<XcxOrder> xcxOrderList = xcxOrderDao.getXcxOrderByStatus(6);
        for (XcxOrder xcxOrder : xcxOrderList) {
            if (xcxOrder.getPayType() == 1) {
                xcxRefundPay(xcxOrder.getOrderId(), xcxOrder.getOrderCode(), xcxOrder.getTransactionNo(), Double.valueOf(xcxOrder.getOrderPrice().toString()));
            } else if (xcxOrder.getPayType() == 4) {
                //根据用户Id，更改（增加）可用预存款金额
                depositService.updatePrice(xcxOrder.getUserId(), xcxOrder.getOrderPrice());
                //增加当前用户流水记录 表bk_deposit_recorder
                depositRecorderService.insertByRefund(xcxOrder.getUserId(), 3, xcxOrder.getOrderCode(), 1, xcxOrder.getOrderPrice());
                //修改订单状态为7(退款成功)
                xcxOrderDao.upPtOrderStatus(xcxOrder.getOrderId(), 7);
                //发送短信
                sendMsgRefund(xcxOrder);
            }
        }
    }

    @Override
    public void XcxPtPayRefundByManual(XcxOrder xcxOrder) {
        logger.info("XcxPtPayRefundByManual");
        if (xcxOrder.getPayType() == 1) {
            xcxRefundPay(xcxOrder.getOrderId(), xcxOrder.getOrderCode(), xcxOrder.getTransactionNo(), Double.valueOf(xcxOrder.getOrderPrice().toString()));
        }
            /*else if(xcxOrder.getPayType()==4){
                //根据用户Id，更改（增加）可用预存款金额
                depositService.updatePrice(xcxOrder.getUserId(),xcxOrder.getOrderPrice());
                //增加当前用户流水记录 表bk_deposit_recorder
                depositRecorderService.insertByRefund(xcxOrder.getUserId(),3,xcxOrder.getOrderCode(),1,xcxOrder.getOrderPrice());
                //修改订单状态为7(退款成功)
                xcxOrderDao.upPtOrderStatus(xcxOrder.getOrderId(),7);
                //发送短信
                sendMsgRefund(xcxOrder);
        }*/
    }

    @Override
    public void checkBeforePay(XcxOrder xcxOrder) {
        List<XcxOpenGroup> xcxOpenGroupList = xcxOpenGroupDao.getXcxOpenGroupByOpenCodeList(xcxOrder.getOpenCode());
        for (XcxOpenGroup xcxOpenGroup : xcxOpenGroupList) {
            if (xcxOpenGroup.getIsOpen() == 1 && xcxOpenGroup.getPtCount() <= 0) {
                throw new ServiceException("此商品已经拼团成功，请重试");
            }
        }
    }

    @Transactional
    public Object xcxRefundPay(Integer orderId, String orderCode, String transactionNo, Double orderPrice) {
        try {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            FileInputStream instream = new FileInputStream(new File(this.getClass().getClassLoader().getResource
                    (GlobalConfigs.getConfigure(GlobalConfigsKey.WeChat.pt_Refund_Certificate)).getPath()));
            try {
                //商户MchId
                keyStore.load(instream, WeChatConfigs.getMchID().toCharArray());
            } finally {
                instream.close();
            }
            //商户MchId
            SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, WeChatConfigs.getMchID().toCharArray()).build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
            org.apache.http.client.methods.HttpPost httppost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund");
            String xml = wxPayRefund(orderCode, transactionNo, String.valueOf((int) (orderPrice * 100)));

            try {
                StringEntity se = new StringEntity(xml);
                httppost.setEntity(se);
                CloseableHttpResponse responseEntry = httpclient.execute(httppost);
                try {
                    HttpEntity entity = responseEntry.getEntity();
                    if (entity != null) {
                        JSONObject result = new JSONObject();
                        SAXReader saxReader = new SAXReader();
                        Document document = saxReader.read(entity.getContent());
                        Element rootElt = document.getRootElement();
                        String resultcode = "";
                        resultcode = rootElt.elementText("result_code");
                        if (resultcode.equals("SUCCESS")) {
                            result.put("weixinPayUrl", rootElt.elementText("code_url"));
                            result.put("prepayId", rootElt.elementText("prepay_id"));
                            result.put("status", "success");
                            result.put("msg", "success");
                            //成功，更改订单状态
                            xcxOrderDao.upPtOrderStatus(orderId, 7);
                            //发送短信
                            XcxOrder xcxOrder = xcxOrderDao.selectByPrimaryKey(orderId);
                            sendMsgRefund(xcxOrder);
                        } else {
                            result.put("status", "false");
                            result.put("msg", rootElt.elementText("err_code_des"));
                        }
                        return result;
                    }
                    EntityUtils.consume(entity);
                } finally {
                    responseEntry.close();
                }
            } finally {
                httpclient.close();
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            JSONObject result = new JSONObject();
            result.put("status", "error");
            result.put("msg", e.getMessage());
            return result;
        }
    }

    public String wxPayRefund(String out_trade_no, String transaction_id, String total_fee) {
        StringBuffer xml = new StringBuffer();
        String data = null;
        try {
            String nonceStr = this.generateOrderNo();//获取随机字符串
            xml.append("</xml>");
            SortedMap<String, String> parameters = new TreeMap<String, String>();
            parameters.put("appid", WeChatConfigs.getXcxAppId());//小程序ID
            parameters.put("mch_id", WeChatConfigs.getMchID());//商户号
            parameters.put("nonce_str", nonceStr);//随机字符串
            parameters.put("out_trade_no", out_trade_no);//商户订单号
            //parameters.put("transaction_id", transaction_id);//微信订单号
            parameters.put("out_refund_no", nonceStr);//商户退款单号
            parameters.put("fee_type", "CNY");//币总
            parameters.put("total_fee", total_fee);//订单金额
            parameters.put("refund_fee", total_fee);//退款金额
            parameters.put("op_user_id", WeChatConfigs.getMchID());//商户号
            parameters.put("sign", createSign(parameters, WeChatConfigs.getApiSecret()));//API密钥
            data = PayCommonUtil.getRequestXml(parameters);
        } catch (Exception e) {
            System.err.println(e.getMessage());
            return null;
        }
        return data;
    }

    public String createSign(SortedMap<String, String> packageParams, String AppKey) {
        StringBuffer sb = new StringBuffer();
        Set es = packageParams.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + AppKey);
        String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
        return sign;
    }

    //退款，短信通知
    public String sendMsgRefund(XcxOrder xcxOrder) {
        //获取用户的手机号
        Customer customer = customerDao.getCustomerById(xcxOrder.getUserId());
        String str = "";
        if (customer != null) {
            logger.info("发送短信开始，手机：{}", customer.getCustomerMobile());
            Map<String, String> map = new HashMap<String, String>();
            map.put("method", "sendMsg");
            map.put("username", "JSM40225");//此处填写用户账号
            map.put("password", "2z4jdhhr");//此处填写用户密码
            map.put("veryCode", "6ksjpzqkfiqu");
            map.put("mobile", customer.getCustomerMobile());//此处填写发送号码
            map.put("tempid", "JSM40225-0008");//此处填写模板短信编号
            map.put("content", "@1@=" + xcxOrder.getOrderPrice());//此处填写模板短信内容
            map.put("msgtype", "2");
            str = com.ibiaoke.common.utils.HttpPost.doPost("http://112.74.76.186:8030/service/httpService/httpInterface.do", map, "GBK");
            logger.info("发送短信结束，手机：{}，短信模板：{}，短信内容：{}。\n返回码:{}", customer.getCustomerMobile(), "JSM40225-0008", "好可惜，您的拼团队伍在24小时内人数未达标，您所支付的金额" + xcxOrder.getOrderPrice() + "元已原路返还", str);
            return str;
        }
        return str;
    }

    @Override
    public XcxOrder getXcxOrderByOrderId(Integer xcxOrderId) {
        AssertUtils.notNull(xcxOrderId, "订单号不能为空");
        XcxOrder xcxOrder = xcxOrderDao.selectByPrimaryKey(xcxOrderId);
        AssertUtils.notNull(xcxOrder, "订单数据异常");
        XcxGoods xcxGoods = xcxGoodsDao.selectByPrimaryKey(xcxOrder.getGoodId());
        AssertUtils.notNull(xcxGoods, "订单商品数据异常");
        xcxOrder.setXcxGoods(xcxGoods);
        return xcxOrder;
    }

    @Override
    public HashMap<String, DateAnalysisVO> getTodayOrderData(XcxOrderSO xcxOrderSO, Page page) {
        Date startTime = DateUtils.theDayBegin(0);
        Date endTime = DateUtils.theDayBegin(1);

        xcxOrderSO.setCreateTime(startTime);
        xcxOrderSO.setEndTime(endTime);

        return getOrderAnalysis(xcxOrderSO, page);
    }

    @Override
    public HashMap<String, DateAnalysisVO> getOrderAnalysis(XcxOrderSO xcxOrderSO, Page page) {
        xcxOrderSO.setDateAnalysis(true);
        List<XcxOrder> list = xcxOrderDao.xcxPtOrderList(xcxOrderSO, page);
        List<XcxOrder> listByExpress = new ArrayList<>();
        List<XcxOrder> listByOneSelf = new ArrayList<>();
        List<XcxOrder> listByPt = new ArrayList<>();
        //总的
        DateAnalysisVO dateAnalysisVOAll = getDateAnalysisVO(list);
        for (XcxOrder xcxOrder : list) {
            //快递配送
            if (xcxOrder.getDeliveryType() == XcxOrderStatusConst.DELIVERY_TYPE_EXPRESS && xcxOrder.getOrderType() == XcxOrderStatusConst.ORDER_TYPE_ZC) {
                listByExpress.add(xcxOrder);
            }
            //门店自提
            if (xcxOrder.getDeliveryType() == XcxOrderStatusConst.DELIVERY_TYPE_ARIIVE && xcxOrder.getOrderType() == XcxOrderStatusConst.ORDER_TYPE_KJ) {
                listByOneSelf.add(xcxOrder);
            }
            //拼团订单
            if ((xcxOrder.getDeliveryType() == XcxOrderStatusConst.DELIVERY_TYPE_ARIIVE && xcxOrder.getOrderType() == XcxOrderStatusConst.ORDER_TYPE_KT) || (xcxOrder.getOrderType() == XcxOrderStatusConst.ORDER_TYPE_KT && xcxOrder.getDeliveryType() == XcxOrderStatusConst.DELIVERY_TYPE_ARIIVE)) {
                listByPt.add(xcxOrder);
            }
        }
        //线上
        DateAnalysisVO dateAnalysisVOExpress = getDateAnalysisVO(listByExpress);
        //快捷支付
        DateAnalysisVO dateAnalysisVOOneSelf = getDateAnalysisVO(listByOneSelf);
        //团购
        DateAnalysisVO dateAnalysisVOPt = getDateAnalysisVO(listByPt);

        HashMap map = new HashMap<String, DateAnalysisVO>();
        map.put("dateAnalysisVOAll", dateAnalysisVOAll);
        map.put("dateAnalysisVOExpress", dateAnalysisVOExpress);
        map.put("dateAnalysisVOOneSelf", dateAnalysisVOOneSelf);
        map.put("dateAnalysisVOPt", dateAnalysisVOPt);
        return map;
    }


    private DateAnalysisVO getDateAnalysisVO(List<XcxOrder> xcxOrders) {
        DateAnalysisVO dateAnalysisVO = new DateAnalysisVO();
        if (CollectionUtils.isNotEmpty(xcxOrders)) {
            BigDecimal totalPrice = xcxOrders.stream().map(XcxOrder::getOrderPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            dateAnalysisVO.setTotalPrice(totalPrice);
            dateAnalysisVO.setTradeCount(xcxOrders.size());
            //BigDecimal的除法,2位精确度，HALF_EVEN舍入法
            dateAnalysisVO.setCustomerPrice(totalPrice.divide(new BigDecimal(xcxOrders.size()), 2, RoundingMode.HALF_EVEN));
        }
        return dateAnalysisVO;
    }

    /****************************************新版购物车下单****************************************/
    @Override
    public List<XcxOrder> submitShoppingCartOrder(SubmitOrderSO submitOrderSO) {
        AssertUtils.notBlank(submitOrderSO.getShoppingCartIds(), "请选择商品");
        AssertUtils.notNull(submitOrderSO.getUserId(), "请先登录");
        //自提订单
        if ("1".equals(submitOrderSO.getDeliveryType())) {
            String[] shoppingCartIds = submitOrderSO.getShoppingCartIds().split(CommonConsts.SPLIT_CHAR);
            List<Integer> shoppingCartIdList = Arrays.asList(shoppingCartIds).stream().map(Integer::parseInt).collect(toList());
            List<ShoppingCart> shoppingCarts = shoppingCartDao.listShoppingCart(shoppingCartIdList);

            List<Integer> cartIds = Lists.newArrayList();
            List<Integer> shopIds = Lists.newArrayList();
            shoppingCarts.forEach(shoppingCart -> {
                cartIds.add(shoppingCart.getCartId());
            });
            shoppingCarts.forEach(shoppingCart -> {
                shopIds.add(shoppingCart.getShopId());
            });
            List<ShoppingCartGoods> shoppingCartGoodsList = shoppingCartGoodsService.listCartGoods(cartIds, shopIds);
            shoppingCarts.forEach(shoppingCart -> shoppingCartGoodsList.forEach(shoppingCartGoods -> {
                        if (Objects.equals(shoppingCart.getCartId(), shoppingCartGoods.getShoppingcartId()) && Objects.equals(shoppingCart.getShopId(), shoppingCartGoods.getShopId())) {
                            shoppingCart.setShoppingCartGoods(shoppingCartGoods);
                        }
                    }
            ));


            List<Integer> shopCartIds = Lists.newArrayList();
            shopCartIds = shoppingCarts.stream().map(ShoppingCart::getShopId).distinct().collect(toList());


            List<DeliverInfoDTO> dtoList = new ArrayList<DeliverInfoDTO>();
            for (int i = 0; i < shopCartIds.size(); i++) {
                DeliverInfoDTO deliverInfoDTO = new DeliverInfoDTO();
                deliverInfoDTO.setShopId((shopCartIds.get(i)));
                dtoList.addAll(Collections.singleton(deliverInfoDTO));
            }

            if (dtoList != null) {
                dtoList.forEach(deliverInfoDTO -> {
                    BigDecimal goodsPrice = shoppingCarts.stream()
                            .filter(shoppingCart -> shoppingCart.getShopId().equals(deliverInfoDTO.getShopId()))
                            .map(shoppingCart -> shoppingCart.getShoppingCartGoods().getGoodsPrice().multiply(new BigDecimal(shoppingCart.getShoppingCartGoods().getNum())))
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                    deliverInfoDTO.setProductPrice(goodsPrice);
                });

                List<String> xcxOrderCodes = Lists.newArrayList();
                dtoList.forEach(deliverInfoDTO -> {
                    XcxOrder xcxOrder = new XcxOrder();
                    xcxOrder.setShopId(deliverInfoDTO.getShopId());
                    xcxOrder.setOrderCode(generateOrderNo());
                    xcxOrder.setOrderStatus(OrderStatusConst.UNPAID);
                    xcxOrder.setUserId(submitOrderSO.getUserId());
                    xcxOrder.setOrderPrice(deliverInfoDTO.getProductPrice());
                    xcxOrder.setExpressPrice(BigDecimal.valueOf(0));
                    xcxOrder.setDeliveryType(CommonConsts.YES);
                    xcxOrder.setRemarke(submitOrderSO.getRemarke());
                    xcxOrder.setDelStatus((byte) CommonConsts.NO);
                    xcxOrder.setSource(submitOrderSO.getSource());
                    xcxOrder.setUpdateTime(new Date());
                    xcxOrder.setCreateTime(new Date());
                    xcxOrderDao.insertSelective(xcxOrder);
                    xcxOrderCodes.add(xcxOrder.getOrderCode());
                });
                shoppingCartService.newDeleteShopppingCart(submitOrderSO.getUserId(), submitOrderSO.getShoppingCartIds());
                return xcxOrderDao.getOrderByOrderCodeList(xcxOrderCodes);
            }
        }
        /******************************快递下单******************************/
        String[] shoppingCartIds = submitOrderSO.getShoppingCartIds().split(CommonConsts.SPLIT_CHAR);
        List<Integer> shoppingCartIdList = Arrays.asList(shoppingCartIds).stream().map(Integer::parseInt).collect(toList());
        List<ShoppingCart> shoppingCarts = shoppingCartDao.listShoppingCart(shoppingCartIdList);

        List<Integer> cartIds = Lists.newArrayList();
        List<Integer> shopIds = Lists.newArrayList();
        shoppingCarts.forEach(shoppingCart -> {
            cartIds.add(shoppingCart.getCartId());
        });
        shoppingCarts.forEach(shoppingCart -> {
            shopIds.add(shoppingCart.getShopId());
        });
        List<ShoppingCartGoods> shoppingCartGoodsList = shoppingCartGoodsService.listCartGoods(cartIds, shopIds);
        shoppingCarts.forEach(shoppingCart -> shoppingCartGoodsList.forEach(shoppingCartGoods -> {
                    if (Objects.equals(shoppingCart.getCartId(), shoppingCartGoods.getShoppingcartId()) && Objects.equals(shoppingCart.getShopId(), shoppingCartGoods.getShopId())) {
                        shoppingCart.setShoppingCartGoods(shoppingCartGoods);
                    }
                }
        ));
        List<Integer> shopCartIds = Lists.newArrayList();
        shopCartIds = shoppingCarts.stream().map(ShoppingCart::getShopId).distinct().collect(toList());
        List<DeliverInfoDTO> dtoList = new ArrayList<DeliverInfoDTO>();
        for (int i = 0; i < shopCartIds.size(); i++) {
            DeliverInfoDTO deliverInfoDTO = new DeliverInfoDTO();
            deliverInfoDTO.setShopId((shopCartIds.get(i)));
            dtoList.addAll(Collections.singleton(deliverInfoDTO));
        }
        if (dtoList != null) {
            dtoList.forEach(deliverInfoDTO -> {
                BigDecimal goodsPrice = shoppingCarts.stream()
                        .filter(shoppingCart -> shoppingCart.getShopId().equals(deliverInfoDTO.getShopId()))
                        .map(shoppingCart -> shoppingCart.getShoppingCartGoods().getGoodsPrice().multiply(new BigDecimal(shoppingCart.getShoppingCartGoods().getNum())))
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                deliverInfoDTO.setProductPrice(goodsPrice);
            });
            XcxAddress address = xcxAddressDao.selectByPrimaryKey(submitOrderSO.getAddressId());
            for (int i = 0; i < shopCartIds.size(); i++) {
                Integer shopId = shopCartIds.get(i);
                Shop shop = shopService.getShop(shopId);
                double distance = LocationUtils.getDistance(address.getLongitude(), address.getLatitude(), shop.getDesLongitude(), shop.getDesLatitude());
                dtoList.forEach(deliverInfoDTO -> {
                    deliverInfoDTO.setShopId(shopId);
                    deliverInfoDTO.setDistance(distance / 1000);
                    deliverInfoDTO.setDeliveryPrice(BigDecimal.valueOf(deliverInfoDTO.getDistance() * deliverInfoDTO.getDeliverUnit()));
                });
            }
            dtoList.forEach(deliverInfoDTO -> {
                BigDecimal goodsPrice = shoppingCarts.stream()
                        .filter(shoppingCart -> shoppingCart.getShopId().equals(deliverInfoDTO.getShopId()))
                        .map(shoppingCart -> shoppingCart.getShoppingCartGoods().getGoodsPrice().multiply(new BigDecimal(shoppingCart.getShoppingCartGoods().getNum())))
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                deliverInfoDTO.setProductPrice(goodsPrice);
            });
            List<String> xcxOrderCodes = Lists.newArrayList();
            dtoList.forEach(deliverInfoDTO -> {
                XcxOrder xcxOrder = new XcxOrder();
                xcxOrder.setShopId(deliverInfoDTO.getShopId());
                xcxOrder.setOrderCode(generateOrderNo());
                xcxOrder.setOrderStatus(OrderStatusConst.UNPAID);
                xcxOrder.setUserId(submitOrderSO.getUserId());
                xcxOrder.setOrderPrice(deliverInfoDTO.getProductPrice());
                xcxOrder.setExpressPrice(deliverInfoDTO.getDeliveryPrice());
                xcxOrder.setDeliveryType(CommonConsts.YES);
                xcxOrder.setRemarke(submitOrderSO.getRemarke());
                xcxOrder.setDelStatus((byte) CommonConsts.NO);
                xcxOrder.setSource(submitOrderSO.getSource());
                xcxOrder.setDeliveryLocationId(address.getAddressId());
                xcxOrder.setDeliveryAddress(address.toDetailAddress());
                xcxOrder.setContactMobile(address.getContactPhone());
                xcxOrder.setContactPersion(address.getContactName());
                xcxOrder.setLongitude(address.getLongitude());
                xcxOrder.setLatitude(address.getLatitude());
                xcxOrder.setUpdateTime(new Date());
                xcxOrder.setCreateTime(new Date());
                xcxOrderDao.insertSelective(xcxOrder);
                xcxOrderCodes.add(xcxOrder.getOrderCode());
            });
            shoppingCartService.newDeleteShopppingCart(submitOrderSO.getUserId(), submitOrderSO.getShoppingCartIds());
            return xcxOrderDao.getOrderByOrderCodeList(xcxOrderCodes);
        }
        return null;
    }
}